﻿#include "ssSocketDef.h"
#include <cstdio>

namespace StarSeeker
{
////////////////////////////监听用的SOCKET//////////////////////////////////
ssSocket::ssSocket()
{
	m_session = 0;
	m_socket = INVALID_SOCKET;
	memset(&m_addr, 0, sizeof(SockAddr_u));
}
ssSocket::~ssSocket()
{
	Detach();
}
u32 ssSocket::GetSession() const
{
	return m_session;
}
SOCKET ssSocket::GetSocket() const
{
	return m_socket;
}
bool ssSocket::IsInvalidSocket() const
{
	return m_socket == INVALID_SOCKET;
}
void ssSocket::Attach(SOCKET s, SockAddr_u& addr, u32 session)
{
	m_socket = s;
	m_addr = addr;
	m_session = session;
}
void ssSocket::Detach()
{
	CloseSocket();
	m_session = 0;
}
void ssSocket::CloseSocket()
{
	if (m_socket != INVALID_SOCKET)
	{
		CloseOneSocket(m_socket);
	}
}
bool ssSocket::IsIPv6() const
{
	return m_addr.addr.sa_family==AF_INET6;
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////AcceptSocket////////////////////////////////////
void ssAcceptSocket::InitBuffer(u32 sendSize, u32 recvSize)
{
	m_sendBuf.Init(sendSize);
	m_recvBuf.Init(recvSize);
	m_recvBuf.Empty();
	m_sendBuf.Empty();
}
int ssAcceptSocket::SendBuffer()
{
	if (m_sendBuf.Size() > 0)
	{
		int ret = send(m_socket, m_sendBuf.Buf(), m_sendBuf.Size(), 0);
		m_sendBuf.Empty();
		return ret;
	}
	return 0;
}
int ssAcceptSocket::RecvBuffer()
{
	if (!m_recvBuf.IsFull())
	{
		int ret = recv(m_socket, m_recvBuf.CurrentBuf(), m_recvBuf.ResidueSize(), 0);
		if (ret >= 0)
		{
			m_recvBuf.AddSize(ret);
			return ret;
		}
		else
		{
			int err = GetSocketError();
			if (err == NONBLOCK_ERROR_1 || err == NONBLOCK_ERROR_2)
			{
				ret = 0;
			}
		}
		return ret;
	}
	return 0;
}
///////////////////////////////////////////////////////////////////////////
////////////////////////////ClientSocket///////////////////////////////////
ssClientSocket::ssClientSocket()
{
	m_createTime = 0;
}
bool32 ssClientSocket::Connect(bool v6, u32 session, const char * ip, u16 port)
{
	bool32 ret = 0;
	if (m_socket != INVALID_SOCKET)
	{
		return -1;
	}
	if (v6)
	{
		ret = ConnectToServerV6(ip, port, m_socket, &m_addr.addrin6);
	}
	else
	{
		ret = ConnectToServer(ip, port, m_socket, &m_addr.addrin);
	}
	m_session = session;
	return ret;
}
///////////////////////////////////////////////////////////////////////////
////////////////////////////ListenSocket///////////////////////////////////
bool32 ssListenSocket::Listen(bool v6, u32 session, const char * ip, u16 port)
{
	bool32 ret = 0;
	if (m_socket != INVALID_SOCKET)
	{
		return -1;
	}
	if (v6)
	{
		ret = ListenPortV6(ip, port, m_socket, &m_addr.addrin6);
	}
	else
	{
		ret = ListenPort(ip, port, m_socket, &m_addr.addrin);
	}
	m_session = session;
	return ret;
}
SOCKET ssListenSocket::Accept()
{
	return AcceptListen(m_socket);
}
ssAcceptSocket ssListenSocket::Accept2(u32 session)
{
	ssAcceptSocket as;
	SOCKET s = INVALID_SOCKET;
	SockAddr_u addr;
	if (IsIPv6())
		s = AcceptListenV6(m_socket, &addr.addrin6);
	else
		s = AcceptListen(m_socket, &addr.addrin);
	as.Attach(s, addr, session);
	return as;
}
///////////////////////////////////////////////////////////////////////////
}
